package com.garden.rocketmq.learn.demo.producer;

import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * 顺序生产者 发送顺序消息
 * 用于注重消息顺序的场景，如订单消息，相同订单号的创建，付款，推送，完成消息有序
 * Created by Garden on 2020/8/4.
 */
public class OrderProducer {

    public static void main(String[] args) throws MQClientException, UnsupportedEncodingException, RemotingException, InterruptedException, MQBrokerException {
        //实例化消息生产者Producer
        DefaultMQProducer producer = new DefaultMQProducer("order_producer_group");
        //设置NameServer的地址，Producer启动后通过NameServer获取目标Topic的路由信息
        producer.setNamesrvAddr("localhost:9876");
        //启动Producer实例
        producer.start();

        //发送消息【模拟有序订单消息场景】
        //构建订单消息列表
        List<Order> orderList = new OrderProducer().buildOrders();
        for (int i = 0; i < orderList.size(); i++) {
            //创建消息，指定主题Topic，标签Tag，业务标识Key，消息体MsgBody [Tag可用于消息过滤，Key可用于消息查询]
            Message message = new Message("test_topic","order_producer_tag"
                    ,"order_producer_key." + orderList.get(i).getId()
                    ,("OrderProducer Msg." + orderList.get(i).getId()).getBytes(RemotingHelper.DEFAULT_CHARSET));
            producer.send(message, new MessageQueueSelector() {
                //设置消息队列选择策略
                @Override
                public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
                    //根据订单id选择消息队列
                    Long orderId = (Long) o;
                    long index = orderId % list.size();
                    return list.get((int)index);
                }
            },orderList.get(i).getId());
        }
    }

    /**
     * 订单类
     */
    private static class Order {
        /**
         * 订单id
         */
        private long id;
        /**
         * 订单描述，代表顺序
         */
        private String desc;

        public long getId() {
            return id;
        }
        public void setId(long id) {
            this.id = id;
        }
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }

        @Override
        public String toString() {
            return "Order{" +
                    "id=" + id +
                    ", desc='" + desc + '\'' +
                    '}';
        }
    }

    /**
     * 生成订单模拟数据【相同订单号有序，不同订单号无序】
     */
    private List<Order> buildOrders(){
        List<Order> orderList = new ArrayList<>();

        Order order = new Order();
        order.setId(15103111039L);
        order.setDesc("创建");
        orderList.add(order);

        order = new Order();
        order.setId(15103111065L);
        order.setDesc("创建");
        orderList.add(order);

        order = new Order();
        order.setId(15103111039L);
        order.setDesc("付款");
        orderList.add(order);

        order = new Order();
        order.setId(15103117235L);
        order.setDesc("创建");
        orderList.add(order);

        order = new Order();
        order.setId(15103111065L);
        order.setDesc("付款");
        orderList.add(order);

        order = new Order();
        order.setId(15103117235L);
        order.setDesc("付款");
        orderList.add(order);

        order = new Order();
        order.setId(15103111065L);
        order.setDesc("完成");
        orderList.add(order);

        order = new Order();
        order.setId(15103111039L);
        order.setDesc("推送");
        orderList.add(order);

        order = new Order();
        order.setId(15103117235L);
        order.setDesc("完成");
        orderList.add(order);

        order = new Order();
        order.setId(15103111039L);
        order.setDesc("完成");
        orderList.add(order);

        return orderList;
    }
}
